﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

using KingsSharp.Core.Data.Entity.Migrations;
using KingsSharp.Common;
using KingsSharp.Common.Secutiry;


namespace KingsSharp.Core.Data.Entity
{
    /// <summary>
    /// 数据库初始化操作类
    /// </summary>
    public class DatabaseInitializer
    {
        private static readonly ICollection<Assembly> MapperAssemblies = AppDomain.CurrentDomain.GetAssemblies();
        /// <summary>
        /// 数据库上下文实体映射规则委托
        /// </summary>
        public static Func<ICollection<Assembly>, string, Type[]> AssemblyRelation;

        /// <summary>
        /// 数据库上下文实体创建委托
        /// </summary>
        public static Func<string, AbstractDbContext> CreateDbContextFactory = connectionstring =>
        { return new DefualtDbContext(); };

        /// <summary>
        /// 获取 数据实体映射配置信息集合
        /// </summary>
        public static ICollection<IEntityMapper> EntityMappers { get { return GetAllEntityMapper(); } }

        /// <summary>
        /// 连接字符串解密
        /// </summary>
        public static Func<string, string> DesConnectionString;

        /// <summary>
        /// 设置数据库初始化，策略为自动迁移到最新版本
        /// </summary>
        public static void Initialize()
        {

            //Database.SetInitializer(new BaseDatabaseInitializer<DefualtDbContext,
            //    DefualtMigrationsConfiguration>());

            //Database.SetInitializer(new BaseDatabaseInitializer<OneDbContext,
            //    OneMigrationsConfiguration>());

            DefualtDbContext context = new DefualtDbContext();
            ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
            StorageMappingItemCollection mappingItemCollection = (StorageMappingItemCollection)objectContext.ObjectStateManager
                .MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
            mappingItemCollection.GenerateViews(new List<EdmSchemaError>());
            context.Dispose();
        }

        private static ICollection<IEntityMapper> GetAllEntityMapper()
        {
            Type baseType = typeof(IEntityMapper);
            Type[] mapperTypes = MapperAssemblies.SelectMany(assembly => assembly.GetTypes())
                .Where(type => baseType.IsAssignableFrom(type) && type != baseType && !type.IsAbstract).ToArray();
            ICollection<IEntityMapper> result = mapperTypes.Select(type => Activator.CreateInstance(type) as IEntityMapper).ToList();
            return result;
        }
        public static ICollection<IEntityMapper> GetAllEntityMapper(string ConnectionString)
        {
            Type[] tempTypes = AssemblyRelation(MapperAssemblies, ConnectionString);
            Type baseType = typeof(IEntityMapper);
            Type[] mapperTypes = tempTypes
                .Where(type => baseType.IsAssignableFrom(type) && type != baseType && !type.IsAbstract).ToArray();
            ICollection<IEntityMapper> result = mapperTypes.Select(type => Activator.CreateInstance(type) as IEntityMapper).ToList();
            return result;
        }
    }
}